package com.css.zfzx.sjcj.modules.service.impl;

import com.css.bpm.platform.constants.PlatformConstants;
import com.css.bpm.platform.utils.PlatformDateUtils;
import com.css.bpm.platform.utils.UUIDGenerator;
import com.css.zfzx.sjcj.common.MenuInfo;
import com.css.zfzx.sjcj.common.ProgressEnum;
import com.css.zfzx.sjcj.common.division.repository.MyDivisionRepository;
import com.css.zfzx.sjcj.common.utils.ServerUtil;
import com.css.zfzx.sjcj.common.vo.DivisionVo;
import com.css.zfzx.sjcj.modules.pojo.DivisionData;
import com.css.zfzx.sjcj.modules.pojo.RespondParams;
import com.css.zfzx.sjcj.modules.pojo.UpdateVo;
import com.css.zfzx.sjcj.modules.repository.PcProgressFillNativeRepository;
import com.css.zfzx.sjcj.modules.pojo.PcProgressFillEntity;
import com.css.zfzx.sjcj.modules.repository.PcProgressFillRepository;
import com.css.zfzx.sjcj.modules.service.PcProgressFillService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.constraints.Null;

/**
 * @Description: pc-statistics
 * @Author: lhl
 * @CreateDate: 2021/7/6 16:22
 */
@Log4j2
@Service
public class PcProgressFillServiceImpl implements PcProgressFillService {

    @Autowired
    private MyDivisionRepository myDivisionRepository;
    @Autowired
    private PcProgressFillRepository pcProgressFillRepository;
    @Autowired
    private PcProgressFillNativeRepository pcProgressFillNativeRepository;

    @Override
    public List<RespondParams> findByTaskCode(String taskCode, HttpServletRequest req) {
        HttpSession session = req.getSession();
        String userId = (String) session.getAttribute(PlatformConstants.CUR_USER_ID_IN_SESSION);

        List<RespondParams> respondParamsList = new ArrayList<>();
        List<DivisionVo> allProvince = myDivisionRepository.getAllProvince();
        List<PcProgressFillEntity> pcEntities = pcProgressFillNativeRepository.findByTaskCode(taskCode, userId);
        if (StringUtils.isEmpty(taskCode)) {
            RespondParams respondParams = new RespondParams();
            List<DivisionData> divisionDataList = getDivisionDataList(allProvince, pcEntities, "1", taskCode);
            respondParams.setDivisionDataList(divisionDataList);

            ProgressEnum progressEnum = ProgressEnum.getInstanceByName("1");
            respondParams.setTaskCode(progressEnum.getMenuId());
            respondParams.setTaskName(progressEnum.getMenuName());
            respondParams.setParentCode(progressEnum.getPid());
            respondParams.setLevel(Integer.valueOf(progressEnum.getLevel()));

            respondParamsList.add(respondParams);
        } else {
            List<MenuInfo> menuInfoList = ProgressEnum.getMenuInfo();
            for (MenuInfo menuInfo : menuInfoList) {
                if (taskCode.equals(menuInfo.getPid())) {
                    RespondParams respondParams = new RespondParams();
                    List<DivisionData> divisionDataList = getDivisionDataList(allProvince, pcEntities, menuInfo.getMenuId(),
                            taskCode);
                    respondParams.setDivisionDataList(divisionDataList);

                    respondParams.setTaskCode(menuInfo.getMenuId());
                    respondParams.setTaskName(menuInfo.getMenuName());
                    respondParams.setParentCode(menuInfo.getPid());
                    respondParams.setLevel(Integer.valueOf(menuInfo.getLevel()));

                    respondParamsList.add(respondParams);
                }
            }
        }
        return respondParamsList;
    }

    public List<DivisionData> getDivisionDataList(List<DivisionVo> allProvince, List<PcProgressFillEntity> pcEntities
            , String menuId, String taskCode) {
        List<DivisionData> divisionDataList = new ArrayList<>();
        for (DivisionVo divisionVo : allProvince) {
            DivisionData divisionData = new DivisionData();
            divisionData.setDivisionName(divisionVo.getProvinceName());
            String divisionCode = divisionVo.getProvinceCode();
            divisionData.setDivisionCode(divisionVo.getProvinceCode());

            int collectionCount = 0;
            int qualityCount = 0;
            double progressValue = 0.0;
            for (PcProgressFillEntity pcEntity : pcEntities) {
                if (StringUtils.isEmpty(taskCode)) {
                    if (divisionCode.equals(pcEntity.getDivisionCode())) {
                        progressValue = progressValue + pcEntity.getProgressValue();
                        /*collectionCount = collectionCount + pcEntity.getCollectionCount();
                        qualityCount = qualityCount + pcEntity.getQualityCount();*/
                    }
                } else {
                    if (taskCode.equals(pcEntity.getParentCode()) && divisionCode.equals(pcEntity.getDivisionCode()) && menuId.equals(pcEntity.getTaskCode())) {
                        progressValue = pcEntity.getProgressValue();
                        //progressValue = progressValue + pcEntity.getProgressValue();
                        /*collectionCount = collectionCount + pcEntity.getCollectionCount();
                        qualityCount = qualityCount + pcEntity.getQualityCount();*/
                    }
                }
            }
            if (StringUtils.isEmpty(taskCode)) {
                progressValue = progressValue / ProgressEnum.getSum(menuId);
            }
            divisionData.setProgressValue(Math.floor(progressValue / 1.0));
            // divisionData.setCollectionCount(String.valueOf(collectionCount));
            // divisionData.setQualityCount(String.valueOf(qualityCount));

            divisionDataList.add(divisionData);
        }
        return divisionDataList;
    }


    @Override
    public RespondParams findAll() {
        RespondParams respondParams = new RespondParams();
        List<DivisionVo> allProvince = myDivisionRepository.getAllProvince();
        List<PcProgressFillEntity> sonPcEntities = new ArrayList<>();
        List<PcProgressFillEntity> grandsonPcEntities = new ArrayList<>();
        List<PcProgressFillEntity> pcEntities = pcProgressFillRepository.findAll();
        for (PcProgressFillEntity entity : pcEntities) {
            if (entity.getLevel() == 1) {
                sonPcEntities.add(entity);
            } else if (entity.getLevel() == 2) {
                grandsonPcEntities.add(entity);
            }
        }
        ProgressEnum anEnum = ProgressEnum.getInstanceByName("1");
        String menuId = anEnum.getMenuId();
        respondParams.setTaskCode(menuId);
        respondParams.setTaskName(anEnum.getMenuName());
        respondParams.setLevel(Integer.valueOf(anEnum.getLevel()));
        List<DivisionData> divisionDataList = new ArrayList<>();
        double progressValue = 0.0;
        for (DivisionVo divisionVo : allProvince) {
            DivisionData divisionData = new DivisionData();
            divisionData.setDivisionCode(divisionVo.getProvinceCode());
            divisionData.setDivisionName(divisionVo.getProvinceName());
            divisionData.setProgressValue(progressValue);
            divisionDataList.add(divisionData);
        }
        respondParams.setDivisionDataList(divisionDataList);

        List<RespondParams> sonList = new ArrayList<>();
        List<MenuInfo> sonMenuInfos = ProgressEnum.getSonMenuInfo(menuId);
        for (MenuInfo sonMenuInfo : sonMenuInfos) {
            RespondParams sonRespondParams = getSonRespondParams(sonMenuInfo, allProvince,
                    sonPcEntities);
            //sonRespondParams.setState("closed");
            List<RespondParams> grandsonList = new ArrayList<>();
            List<MenuInfo> grandsonMenuInfos = ProgressEnum.getSonMenuInfo(sonMenuInfo.getMenuId());
            for (MenuInfo grandsonMenuInfo : grandsonMenuInfos) {
                RespondParams grandsonRespondParams = getSonRespondParams(grandsonMenuInfo, allProvince,
                        grandsonPcEntities);

                grandsonList.add(grandsonRespondParams);
            }
            sonRespondParams.setChildren(grandsonList);

            sonList.add(sonRespondParams);
        }
        respondParams.setChildren(sonList);

        return respondParams;
    }

    public RespondParams getSonRespondParams(MenuInfo sonMenuInfo, List<DivisionVo> allProvince,
                                             List<PcProgressFillEntity> sonPcEntities) {
        String sonMenuId = sonMenuInfo.getMenuId();
        RespondParams sonRespondParams = new RespondParams();
        sonRespondParams.setTaskCode(sonMenuId);
        sonRespondParams.setTaskName(sonMenuInfo.getMenuName());
        sonRespondParams.setParentCode(sonMenuInfo.getPid());
        sonRespondParams.setLevel(Integer.valueOf(sonMenuInfo.getLevel()));

        List<DivisionData> sonDivisionDataList = new ArrayList<>();
        for (DivisionVo divisionVo : allProvince) {
            double sonProgressValue = 0.0;
            String provinceCode = divisionVo.getProvinceCode();
            DivisionData divisionData = new DivisionData();
            divisionData.setDivisionCode(divisionVo.getProvinceCode());
            divisionData.setDivisionName(divisionVo.getProvinceName());
            for (PcProgressFillEntity entity : sonPcEntities) {
                if (sonMenuId.equals(entity.getTaskCode()) && provinceCode.equals(entity.getDivisionCode())) {
                    sonProgressValue = entity.getProgressValue();
                    break;
                }
            }
            divisionData.setProgressValue(sonProgressValue);
            sonDivisionDataList.add(divisionData);
        }
        sonRespondParams.setDivisionDataList(sonDivisionDataList);
        return sonRespondParams;
    }

    @Override
    public void updatePcProgressFill(List<UpdateVo> voList, HttpServletRequest req) {
        String userId = ServerUtil.getUserId(req);
        List<DivisionVo> allProvince = myDivisionRepository.getAllProvince();
        List<PcProgressFillEntity> sonPcEntities = new ArrayList<>();
        List<PcProgressFillEntity> grandsonPcEntities = new ArrayList<>();
        List<PcProgressFillEntity> pcEntities = pcProgressFillRepository.findAll();
        for (PcProgressFillEntity entity : pcEntities) {
            if (entity.getLevel() == 1) {
                sonPcEntities.add(entity);
            } else if (entity.getLevel() == 2) {
                grandsonPcEntities.add(entity);
            }
        }
        List<PcProgressFillEntity> updateList = new ArrayList<>();
        List<PcProgressFillEntity> saveList = new ArrayList<>();
        List<UpdateVo> supSaveList=new ArrayList<>();
        List<UpdateVo> supUpdateList=new ArrayList<>();
        List<String> taskCodes = new ArrayList<>();
        for (UpdateVo vo : voList) {
            if (vo.getProgressValue()<0){
                vo.setProgressValue(0);
            }else if (vo.getProgressValue()>100){
                vo.setProgressValue(100);
            }
            taskCodes.add(vo.getTaskCode());
            String voTaskCode = vo.getTaskCode();
            ProgressEnum anEnum = ProgressEnum.getInstanceByName(voTaskCode);
            String voDivisionCode = vo.getDivisionCode();
            DivisionVo divisionVo=null;
            for (DivisionVo province:allProvince){
                if (voDivisionCode.equals(province.getProvinceCode())){
                    divisionVo=province;
                }
            }
            PcProgressFillEntity pcEntity=null;
            for (PcProgressFillEntity grandsonEntity:grandsonPcEntities){
                if (voTaskCode.equals(grandsonEntity.getTaskCode())&&voDivisionCode.equals(grandsonEntity.getDivisionCode())){
                    grandsonEntity.setProgressValue(vo.getProgressValue());
                    pcEntity=grandsonEntity;
                }
            }
            if (pcEntity==null){
                PcProgressFillEntity saveEntity = new PcProgressFillEntity();
                saveEntity.setProgressId(UUIDGenerator.getUUID());
                saveEntity.setTaskCode(voTaskCode);
                saveEntity.setTaskName(anEnum.getMenuName());
                saveEntity.setDivisionCode(voDivisionCode);
                saveEntity.setDivisionName(divisionVo.getProvinceName());
                saveEntity.setProgressValue(vo.getProgressValue());
                saveEntity.setCreateUser(userId);
                saveEntity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                saveEntity.setParentCode(anEnum.getPid());
                saveEntity.setLevel(Integer.valueOf(anEnum.getLevel()));
                saveEntity.setVersion(1);
                saveList.add(saveEntity);

                if (supSaveList.size()<=0) {
                    UpdateVo updateVo = new UpdateVo();
                    updateVo.setProgressValue(vo.getProgressValue());
                    updateVo.setDivisionCode(vo.getDivisionCode());
                    updateVo.setTaskCode(anEnum.getPid());
                    supSaveList.add(updateVo);
                }else {
                    int size = supSaveList.size();
                    UpdateVo updateVo=null;
                    boolean isNa=true;
                    for (int i=0;i<size;i++){
                        updateVo=supSaveList.get(i);
                        String taskCode = updateVo.getTaskCode();
                        String divisionCode = updateVo.getDivisionCode();
                        if (taskCode.equals(anEnum.getPid()) && divisionCode.equals(vo.getDivisionCode())) {
                            isNa=false;
                            updateVo.setProgressValue(vo.getProgressValue() + updateVo.getProgressValue());
                        }
                    }
                    if (isNa) {
                        updateVo = new UpdateVo();
                        updateVo.setProgressValue(vo.getProgressValue());
                        updateVo.setDivisionCode(vo.getDivisionCode());
                        updateVo.setTaskCode(anEnum.getPid());
                        supSaveList.add(updateVo);
                    }
                }
            }else {
                //pcEntity.setProgressValue(vo.getProgressValue());
                pcEntity.setUpdateUser(userId);
                pcEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
                pcEntity.setVersion(pcEntity.getVersion() + 1);
                updateList.add(pcEntity);

                if (supUpdateList.isEmpty()) {
                    UpdateVo updateVo = new UpdateVo();
                    updateVo.setProgressValue(vo.getProgressValue());
                    updateVo.setDivisionCode(vo.getDivisionCode());
                    updateVo.setTaskCode(anEnum.getPid());
                    supUpdateList.add(updateVo);
                } else {
                    int size = supUpdateList.size();
                    UpdateVo updateVo=null;
                    boolean isNa=true;
                    for (int i=0;i<size;i++){
                        updateVo=supUpdateList.get(i);
                        String taskCode = updateVo.getTaskCode();
                        String divisionCode = updateVo.getDivisionCode();
                        if (taskCode.equals(anEnum.getPid()) && divisionCode.equals(vo.getDivisionCode())) {
                            isNa=false;
                            updateVo.setProgressValue(vo.getProgressValue() + updateVo.getProgressValue());
                        }
                    }
                    if (isNa) {
                        updateVo = new UpdateVo();
                        updateVo.setProgressValue(vo.getProgressValue());
                        updateVo.setDivisionCode(vo.getDivisionCode());
                        updateVo.setTaskCode(anEnum.getPid());
                        supUpdateList.add(updateVo);
                    }
                }
            }
            System.out.println("=====supSaveList{}:" + supSaveList);
            System.out.println("=====supUpdateList{}:" + supUpdateList);
        }

        if (!supSaveList.isEmpty()) {
            for (UpdateVo updateVo : supSaveList) {
                String taskCode = updateVo.getTaskCode();
                ProgressEnum anEnum = ProgressEnum.getInstanceByName(taskCode);
                String divisionCode = updateVo.getDivisionCode();
                DivisionVo divisionVo=null;
                for (DivisionVo province:allProvince){
                    if (divisionCode.equals(province.getProvinceCode())){
                        divisionVo=province;
                    }
                }
                PcProgressFillEntity supEntity = null;
                int index=0;
                Iterator<PcProgressFillEntity> iterator = sonPcEntities.iterator();
                while (iterator.hasNext()){
                    PcProgressFillEntity pcEntity = iterator.next();
                    if (taskCode.equals(pcEntity.getTaskCode())&&divisionCode.equals(pcEntity.getDivisionCode())){
                        index++;
                        if (index==1){
                            supEntity=pcEntity;
                        }
                    }
                    if (index>1){
                        //sonPcEntities.remove(pcEntity);
                        iterator.remove();
                        pcProgressFillRepository.delete(pcEntity);
                    }
                }
                double progressValue = updateVo.getProgressValue();
                if (supEntity == null) {
                    supEntity=new PcProgressFillEntity();
                    supEntity.setProgressId(UUIDGenerator.getUUID());
                    supEntity.setTaskCode(taskCode);
                    supEntity.setTaskName(anEnum.getMenuName());
                    supEntity.setDivisionCode(divisionCode);
                    supEntity.setDivisionName(divisionVo.getProvinceName());

                    for (PcProgressFillEntity pcEntity:grandsonPcEntities){
                        if (taskCode.equals(pcEntity.getParentCode())&&divisionCode.equals(pcEntity.getDivisionCode())){
                            progressValue=progressValue+pcEntity.getProgressValue();
                        }
                    }
                    supEntity.setProgressValue((int) Math.floor(progressValue / ProgressEnum.getSum(taskCode)));

                    supEntity.setCreateUser(userId);
                    supEntity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                    supEntity.setParentCode("1");
                    supEntity.setLevel(1);
                    supEntity.setVersion(1);
                    saveList.add(supEntity);
                } else {
                    for (PcProgressFillEntity pcEntity:grandsonPcEntities){
                        if (taskCode.equals(pcEntity.getParentCode())&&divisionCode.equals(pcEntity.getDivisionCode())){
                            progressValue=progressValue+pcEntity.getProgressValue();
                        }
                    }
                    supEntity.setProgressValue((int) Math.floor(progressValue / ProgressEnum.getSum(taskCode)));
                    updateList.add(supEntity);
                }

            }
        }
        if (!supUpdateList.isEmpty()) {
            for (UpdateVo updateVo : supUpdateList) {
                String taskCode = updateVo.getTaskCode();
                String divisionCode = updateVo.getDivisionCode();
                PcProgressFillEntity supEntity=null;
                int index=0;
                Iterator<PcProgressFillEntity> iterator = sonPcEntities.iterator();
                while (iterator.hasNext()){
                    PcProgressFillEntity pcEntity = iterator.next();
                    if (taskCode.equals(pcEntity.getTaskCode())&&divisionCode.equals(pcEntity.getDivisionCode())){
                        index++;
                        if (index==1){
                            supEntity=pcEntity;
                        }
                    }
                    if (index>1){
                        //sonPcEntities.remove(pcEntity);
                        iterator.remove();
                        pcProgressFillRepository.delete(pcEntity);
                    }
                }
                double progressValue = 0.0;
                for (PcProgressFillEntity grandsonEntity:grandsonPcEntities){
                    if (taskCode.equals(grandsonEntity.getParentCode())&&divisionCode.equals(grandsonEntity.getDivisionCode())){
                        progressValue=progressValue+grandsonEntity.getProgressValue();
                    }
                }
                progressValue = progressValue / ProgressEnum.getSum(taskCode);
                supEntity.setProgressValue((int) Math.floor(progressValue));
                supEntity.setUpdateUser(userId);
                supEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
                supEntity.setVersion(supEntity.getVersion() + 1);
                updateList.add(supEntity);
            }
        }
        System.out.println("saveList{}:" + saveList);
        System.out.println("updateList{}:" + updateList);
        if (saveList.size() > 0) {
            pcProgressFillNativeRepository.batchSave(saveList);
        }
        if (updateList.size() > 0) {
            pcProgressFillNativeRepository.batchUpdate(updateList);
        }
    }

    @Override
    public List<RespondParams> queryProgressCount(String taskCode) {
        List<RespondParams> respondParams = new ArrayList<>();
        //获取34个省的空数据
        List<DivisionVo> allProvince = myDivisionRepository.getAllProvince();
        List<MenuInfo> menuInfoList = ProgressEnum.getMenuInfo();
        //添加任务
        for (MenuInfo menuFirst : menuInfoList) {
            List<DivisionData> divisionDataList = new ArrayList<>();
            for (DivisionVo divisionVo : allProvince) {
                DivisionData divisionData = new DivisionData();
                divisionData.setDivisionName(divisionVo.getProvinceName());
                divisionData.setDivisionCode(divisionVo.getProvinceCode());
                divisionData.setProgressValue(0.00);
                divisionDataList.add(divisionData);
            }
            RespondParams menuData = new RespondParams();
            if (StringUtils.isEmpty(taskCode)) {
                if ("1".equals(menuFirst.getMenuId())) {
                    menuData.setMenuId(menuFirst.getMenuId());
                    menuData.setMenuName(menuFirst.getMenuName());
                    menuData.setLevel(Integer.parseInt(menuFirst.getLevel()));
                    menuData.setParentCode(menuFirst.getPid());
                    menuData.setDivisionDataList(divisionDataList);
                    respondParams.add(menuData);
                }
            } else {
                if ("1".equals(menuFirst.getLevel()) || "2".equals(menuFirst.getLevel())) {
                    if (!taskCode.equals(menuFirst.getPid())) {
                        continue;
                    }
                    menuData.setMenuId(menuFirst.getMenuId());
                    menuData.setMenuName(menuFirst.getMenuName());
                    menuData.setLevel(Integer.parseInt(menuFirst.getLevel()));
                    menuData.setParentCode(menuFirst.getPid());
                    menuData.setDivisionDataList(divisionDataList);
                    respondParams.add(menuData);
                }
            }
        }
        //获取数据库34个省的数据 始终返回34个省
        for (RespondParams respondParams1 : respondParams) {
            List<DivisionData> divisionDataList = respondParams1.getDivisionDataList();
            if (null == divisionDataList) {
                continue;
            }
            for (DivisionData divisionData : divisionDataList) {
                //获取数据库里表单个省的数据，设置给返回集
                Object pcProgressDataSq = pcProgressFillNativeRepository.queryPcProgressDataSq(respondParams1.getMenuId()
                        , respondParams1.getMenuId(), divisionData.getDivisionCode());
                divisionData.setDivisionCode(divisionData.getDivisionCode());
                divisionData.setDivision(divisionData.getDivisionName());
                if (null == pcProgressDataSq) {
                    divisionData.setProgressValue(0);
                    continue;
                }
                Object[] objArray = (Object[]) pcProgressDataSq;
                divisionData.setProgressValue((double) ((Integer) objArray[5]));
//                divisionData.setCollectionCount((String) objArray[6]);
//                divisionData.setQualityCount((String) objArray[5]);
//                System.out.println(divisionData.toString());
            }
        }
        return respondParams;
    }

    public boolean isExistTask(List<RespondParams> queryCountVos, String taskId) {
        if (null == queryCountVos || queryCountVos.size() == 0) {
            return false;
        }
        if (StringUtils.isEmpty(taskId)) {
            return false;
        }
        for (RespondParams respondParams : queryCountVos) {
            if (respondParams.getMenuId().equals(taskId)) {
                return true;
            }
        }
        return false;
    }
}
